
#ifndef _SETTINGSKEEPER_
#define _SETTINGSKEEPER_
#include "Common/Definitions.h"

#include <string>
#include "Common/Strings.h"
#include "Common/Extras.h"
#include "Common/Structures.h"
#include "Runtime.Low/Services/Service.h"
#include "Runtime.Low/Services/Logger/Logger.h"

namespace ttg
{
	namespace services
	{
		//Auxiliary class, which incapsulates one working mode(e.g. resolution "1024x768").
		class SettingsUnit :public structures::NamedObject
		{
			private:
				std::string description;
			public:
				//<fix me>
				int param1;
				int param2;
				//</fix me>
				//creates unit with given name, description and params.
				//Note: name must be unique.
				SettingsUnit(const char *name,
							 const char *description,
							 int param1, int param2 = 0);
				//returns description.
				const char *getDescription() const;
				//returns first param. In future can be modified.
				int getParam1() const;
				//returns second param. In future can be modified.
				int getParam2() const;
				~SettingsUnit();
		};

		//Auxiliary class, which incapsulates one set of modes (e.g. acceptable resolutions).
		class Settings :public structures::NamedObject
		{
			private:
				std::string description;
				structures::Dictionary<SettingsUnit> *data;
				SettingsUnit *chosen;
			public:
				//creates empty class with given name and description
				Settings(const char *name,
						 const char *description);
				//adds SuttingUnit to collection.
				//Note: added unit will not be marked as "chosen". Call "setChosen".
				void add(SettingsUnit *su);
				//Marks given unit as "chosen" and returns it.
				SettingsUnit *setChosen(SettingsUnit *su);
				//returns chosen unit.
				//Note: it can throw NoSuchElementError.
				const SettingsUnit &getChosen() const;
				//Frees class and all added SettingsUnits.
				~Settings();
				//<fix me>
				SettingsUnit &getCurrent();
				const SettingsUnit &getCurrent() const;
				//</fix me>
		};

		//Main class. Loads/saves from/to file settings and gathers information.
		class SettingsKeeper :public Service
		{
			private:
				static SettingsKeeper *ref;
			private:
				structures::Dictionary<Settings> *data;
				void configure(extras::XMLTree &xml);
				//creates empty SettingsKeeper with information about device.
				SettingsKeeper();
			protected:
				virtual void startUnSafe(std::vector<Service *> &deps, const char *params);
				virtual void stopUnSafe();
			public:
				void add(Settings *s);
				//<fix me>
				void load(const char *filename);
				void save(const char *filename);
				//</fix me>
				//return chosen SettingsUnit for Settings with "name".
				//Note: it can throw NoSuchElementError.
				const SettingsUnit &getChosen(const char *name);
				//Frees keeper and all associated with it objects.
				virtual ~SettingsKeeper();
				//Returns reference to instance (which always exists).
				inline static SettingsKeeper *getRef()
				{ return ref == NULL ? (ref = new SettingsKeeper()) : ref; }
		};
	}
}

#endif
